package com.homson.servicedomain.domain.account;

import com.homson.coreservice.servicecommon.co.AccountTransferCO;
import com.homson.coreservice.servicecommon.enumeration.AccountTypeEnum;
import com.homson.coreservice.servicecommon.expection.BizException;
import com.homson.coreservice.serviceinfrastructure.datasource.model.account.AccountDO;
import com.homson.coreservice.serviceinfrastructure.datasource.repository.account.AccountRepository;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Objects;

/**
 * @author: homson_leo
 * @contact: hey_超级巨星（Homson_Leo）- 刘泓岑 1196816884@qq.com
 * @time: 2025/11/1 4:59 PM
 **/
@Service
@Slf4j
public class AccountTransferCommand {
    
    @Resource
    private AccountQueryCommand accountQueryCommand;
    @Resource
    private AccountRepository accountRepository;
    
    @Transactional(rollbackFor = Exception.class)
    public void transferAccountBalance(Long accountId, AccountTransferCO accountTransferCO){
        try{
            AccountTypeEnum accountType = AccountTypeEnum.of(accountTransferCO.getAccountType());
            if(Objects.isNull(accountType)){
                throw new BizException("不支持的账户类型");
            }
            AccountTypeEnum targetAccountType = AccountTypeEnum.of(accountTransferCO.getTargetAccountType());
            if(Objects.isNull(targetAccountType)){
                throw new BizException("不支持的目标账户类型");
            }
    
            Boolean accountExist = accountQueryCommand.isAccountExist(accountId, accountType);
            if(!accountExist){
                throw new BizException("账户不存在");
            }
            Long targetAccountId = accountTransferCO.getTargetAccountId();
            Boolean targetAccountExist = accountQueryCommand.isAccountExist(targetAccountId, targetAccountType);
            if(!targetAccountExist){
                throw new BizException("目标账户不存在");
            }
    
            AccountDO originAccountDO = accountRepository.findByAccountId(accountId);
            AccountDO targetAccountDO = accountRepository.findByAccountId(accountTransferCO.getTargetAccountId());
    
    
            BigDecimal originBalance = originAccountDO.getBalance();
            if(accountTransferCO.getAmount().compareTo(originBalance) > 0){
                throw new BizException("账户余额不足");
            }
            BigDecimal newOriginBalance = originBalance.subtract(accountTransferCO.getAmount());
            BigDecimal targetBalance = targetAccountDO.getBalance().add(accountTransferCO.getAmount());
    
            // 使用CAS进行更新
            accountRepository.updateAccountBalance(accountId, newOriginBalance, originAccountDO.getVersionId());
            accountRepository.updateAccountBalance(targetAccountId, targetBalance, targetAccountDO.getVersionId());
        }catch (BizException bizException){
            log.error(AccountTransferCommand.class.getSimpleName(), bizException.getMessage());
        }
    }
}
